package com.ibeetl.admin.aod.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 线程池工厂,用于构建自动绑定销毁回调的线程池
 */
public class ThreadPoolFactory {

    private static Map<String, ExecutorService> threadPoolMap = new Hashtable<String, ExecutorService>();


    /**
     * 获取指定名称的连接池, 如果不存在,则会自动构建一个,并自动绑定销毁回调
     *
     * @param name         线程池的名称
     * @param initPoolSize 当线程池不存在时初始化的线程池大小
     * @return
     */
    public synchronized static ExecutorService getThreadPool(String name, int initPoolSize) {
        ExecutorService executorService = threadPoolMap.get(name);
        if (executorService == null) {
            executorService = Executors.newFixedThreadPool(initPoolSize);
            threadPoolMap.put(name, executorService);
            Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThreadPool(executorService)));//绑定销毁回调
        }
        return executorService;
    }

    private static class ShutdownThreadPool implements Runnable {

        private final Log log = LogFactory.getLog(this.getClass());

        private ExecutorService executorService;

        public ShutdownThreadPool(ExecutorService executorService) {
            this.executorService = executorService;
        }

        @Override
        public void run() {
            if (this.executorService == null) {
                return;
            }

            this.executorService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow(); // Cancel currently executing tasks
                    if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                        log.error("线程池未正常终止");
                    }
                }
            } catch (InterruptedException ie) {
                executorService.shutdownNow();
            }
        }
    }
}
